﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

namespace Li.DingTalk.Model.Contacts
{
    /// <summary>
    /// 文件管理处理类
    /// </summary>
    public class media
    {

        #region 上传媒体文件获取media_id
        /// <summary>
        /// 上传媒体文件
        /// </summary>
        /// <param name="access_token"></param>
        /// <returns></returns>
        /// 上传媒体文件的限制
        /// 图片（image）:1MB，支持JPG格式
        /// 语音（voice）：2MB，播放长度不超过60s，AMR格式
        /// 普通文件（file）：10MB
        public static uploadfiles Uploadfiles(string access_token, string fileWithPath, string type)
        {
            var path = string.Format("https://oapi.dingtalk.com/media/upload?access_token={0}&type={1}", access_token, type);
            var Upload = "";
            var request = (HttpWebRequest)WebRequest.Create(path);
            var boundary = "----------" + DateTime.Now.Ticks.ToString("x");
            request.ContentType = "multipart/form-data; boundary=" + boundary;
            request.Method = "POST";
            using (Stream requestStream = request.GetRequestStream())
            {
                byte[] boundarybytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
                byte[] trailer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "–-\r\n");
                var filename = Path.GetFileName(fileWithPath);
                using (FileStream fs = new FileStream(fileWithPath, FileMode.Open, FileAccess.Read))
                {
                    byte[] bArr = new byte[fs.Length];
                    fs.Read(bArr, 0, bArr.Length);
                    requestStream.Write(boundarybytes, 0, boundarybytes.Length);
                    var header = $"Content-Disposition:form-data;name=\"media\";filename=\"{filename}\"\r\nfilelength=\"{fs.Length}\"\r\nContent-Type:application/octet-stream\r\n\r\n";
                    byte[] postHeaderBytes = Encoding.UTF8.GetBytes(header.ToString());
                    requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
                    fs.Close();
                    requestStream.Write(bArr, 0, bArr.Length);
                    requestStream.Write(trailer, 0, trailer.Length);
                }
            }
            var response = (HttpWebResponse)request.GetResponse();
            var responseStream = response.GetResponseStream();
            using (var streamReader = new StreamReader(response.GetResponseStream()))
            {
                Upload = streamReader.ReadToEnd();
            }
            return Newtonsoft.Json.JsonConvert.DeserializeObject<uploadfiles>(Upload);
        }

        #endregion

        #region 钉盘
        /// <summary>
        /// 发送文件给指定用户
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="agent_id">文件发送者微应用的agentId</param>
        /// <param name="userid">文件接收人的userid</param>
        /// <param name="media_id">调用钉盘上传文件接口得到的mediaid,需要utf-8 urlEncode</param>
        /// <param name="file_name">文件名(需包含含扩展名),需要utf-8 urlEncode</param>
        /// <returns></returns>
        public static ResultPackage Sendfiles(string access_token, string agent_id, string userid, string media_id, string file_name)
        {
            var path = string.Format("https://oapi.dingtalk.com/cspace/add_to_single_chat?access_token={0}&agent_id={1}&userid={2}&media_id={3}&file_name={4}}", access_token, agent_id, userid, media_id, file_name);
            string resultJson = RequestHelper.Get(path);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<ResultPackage>(resultJson);
        }

        /// <summary>
        /// 新增文件到用户钉盘
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="agent_id">微应用的agentId</param>
        /// <param name="code">	如果是微应用，code值为微应用免登授权码,如果是服务窗应用，code值为服务窗免登授权码。code为临时授权码，只能消费一次，下次请求需要重新获取新的code。</param>
        /// <param name="media_id">调用钉盘上传文件接口得到的mediaid, 需要utf-8 urlEncode</param>
        /// <param name="space_id">调用云盘选择控件后获取的用户钉盘空间ID</param>
        /// <param name="folder_id">调用云盘选择控件后获取的用户钉盘文件夹ID</param>
        /// <param name="name">上传文件的名称，不能包含非法字符，需要utf-8 urlEncode</param>
        /// <param name="overwrite">遇到同名文件是否覆盖，若不覆盖，则会自动重命名本次新增的文件，默认为false</param>
        /// <returns></returns>
        public static adduserfiles Adduserfiles(string access_token, string agent_id, string code, string media_id, string space_id, string folder_id, string name, string overwrite)
        {
            var path = string.Format("https://oapi.dingtalk.com/cspace/add?access_token={0}&agent_id={1}&code={2}&media_id={3}&space_id={4}&folder_id={5}&name={6}&overwrite={7}", access_token, agent_id, code, media_id, space_id, folder_id, name, overwrite);
            string resultJson = RequestHelper.Get(path);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<adduserfiles>(resultJson);
        }

        /// <summary>
        /// 获取企业下的自定义空间
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="domain">企业调用时传入，需要为10个字节以内的字符串，仅可包含字母和数字，大小写不敏感</param>
        /// <param name="agent_id">ISV调用时传入，微应用agentId</param>
        /// <returns></returns>
        public static getenterprisespace Getenterprisespace(string access_token, string domain, string agent_id)
        {
            var path = string.Format("https://oapi.dingtalk.com/cspace/get_custom_space?access_token={0}&agent_id={1}&code={2}", access_token, domain, agent_id);
            string resultJson = RequestHelper.Get(path);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<getenterprisespace>(resultJson);
        }

        /// <summary>
        /// 授权用户访问企业下的自定义空间
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="agent_id">ISV调用时传入，授权访问指定微应用的自定义空间</param>
        /// <param name="domain">企业调用时传入，授权访问该domain的自定义空间</param>
        /// <param name="type">	权限类型，目前支持上传和下载，上传请传add，下载请传download</param>
        /// <param name="userid">企业用户userid</param>
        /// <param name="path">	授权访问的路径，如授权访问所有文件传“/”，授权访问/doc文件夹传“/doc/” 需要utf-8 urlEncode</param>
        /// <param name="fileids">授权访问的文件id列表，id之间用英文逗号隔开，如“fileId1,fileId2”</param>
        /// <param name="duration">	权限有效时间，有效范围为0~3600秒，超出此范围或不传默认为30秒</param>
        /// <returns></returns>
        public static ResultPackage Getuserenterprisespace(string access_token, string agent_id, string domain, string type, string userid, string path, string fileids, int duration)
        {
            var paths = string.Format("https://oapi.dingtalk.com/cspace/add?access_token={0}&domain={1}&agent_id={2}&type={3}&userid={4}&path={5}&fileids={6}&duration={7}", access_token, agent_id, domain, type, userid, path, fileids, duration);
            string resultJson = RequestHelper.Get(paths);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<ResultPackage>(resultJson);
        }

        /// <summary>
        /// 开启文件上传事务
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="agent_id">微应用的agentId</param>
        /// <param name="file_size">文件大小</param>
        /// <param name="chunk_numbers">文件总块数</param>
        /// <returns></returns>
        public static openfileupload Openfileupload(string access_token, string agent_id, int file_size, int chunk_numbers)
        {
            var paths = string.Format("https://oapi.dingtalk.com/file/upload/transaction?access_token={0}&agent_id={1}&file_size={2}&chunk_numbers={3}", access_token, agent_id, file_size, chunk_numbers);
            string resultJson = RequestHelper.Get(paths);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<openfileupload>(resultJson);
        }

        /// <summary>
        /// 上传文件块
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="agent_id">微应用的agentId</param>
        /// <param name="upload_id">上传事务id 需要utf-8 urlEncode</param>
        /// <param name="chunk_sequence">文件块号，从1开始计数</param>
        /// <returns></returns>
        public static ResultPackage Uploadfilefast(string access_token, string agent_id, string upload_id, int chunk_sequence)
        {
            var paths = string.Format("https://oapi.dingtalk.com/file/upload/chunk?access_token={0}&agent_id={1}&upload_id={2}&chunk_sequence={3}", access_token, agent_id, upload_id, chunk_sequence);
            string resultJson = RequestHelper.Get(paths);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<ResultPackage>(resultJson);
        }

        /// <summary>
        /// 提交文件上传事务
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="agent_id">微应用的agentId</param>
        /// <param name="file_size">文件大小</param>
        /// <param name="chunk_numbers">文件总块数</param>
        /// <param name="upload_id">上传事务id 需要utf-8 urlEncode</param>
        /// <returns></returns>
        public static extractingfileupload Extractingfileupload(string access_token, string agent_id, int file_size, int chunk_numbers, string upload_id)
        {
            var paths = string.Format("https://oapi.dingtalk.com/file/upload/transaction?access_token={0}&agent_id={1}&file_size={2}&chunk_numbers={3}&upload_id={4}", access_token, agent_id, file_size, chunk_numbers, upload_id);
            string resultJson = RequestHelper.Get(paths);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<extractingfileupload>(resultJson);
        }

        /// <summary>
        /// 单步文件上传
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="agent_id">微应用的agentId</param>
        /// <param name="file_size">文件大小</param>
        /// <returns></returns>
        public static singlefileupload Singlefileupload(string access_token, string agent_id, int file_size)
        {
            var paths = string.Format("https://oapi.dingtalk.com/file/upload/single?access_token={0}&agent_id={1}&file_size={2}", access_token, agent_id, file_size);
            string resultJson = RequestHelper.Get(paths);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<singlefileupload>(resultJson);
        }

        #endregion



        #region 文件管理信息
        /// <summary>
        /// 上传媒体文件
        /// </summary>
        public class uploadfiles : ResultPackage
        {
            /// <summary>
            /// 媒体文件类型，分别有图片（image）、语音（voice）、普通文件(file)
            /// </summary>
            public string type
            {
                get;
                set;
            }

            /// <summary>
            /// 媒体文件上传后获取的唯一标识
            /// </summary>
            public string media_id
            {
                get;
                set;
            }

            /// <summary>
            /// 媒体文件上传时间戳
            /// </summary>
            public string created_at
            {
                get;
                set;
            }
        }

        /// <summary>
        /// 新增文件到用户钉盘
        /// </summary>
        public class adduserfiles : ResultPackage
        {
            /// <summary>  
            /// 文件的详细信息  
            /// </summary>  
            public string dentry
            {
                get;
                set;
            }

        }

        /// <summary>
        /// 获取企业下的自定义空间
        /// </summary>
        public class getenterprisespace : ResultPackage
        {
            /// <summary>
            /// 	申请到的空间id
            /// </summary>
            public string spaceid
            {
                get;
                set;
            }
        }

        /// <summary>
        /// 开启文件上传事务
        /// </summary>
        public class openfileupload : ResultPackage
        {
            /// <summary>
            /// 上传事务id
            /// </summary>
            public string upload_id
            {
                get;
                set;
            }
        }

        /// <summary>
        /// 提交文件上传事务
        /// </summary>
        public class extractingfileupload : ResultPackage
        {
            /// <summary>
            /// 文件存储id
            /// </summary>
            public string media_id
            {
                get;
                set;
            }
        }

        /// <summary>
        /// 单步文件上传
        /// </summary>
        public class singlefileupload : ResultPackage
        {
            /// <summary>
            /// 文件存储id
            /// </summary>
            public string media_id
            {
                get;
                set;
            }
        }

        #endregion

    }
}
